#ifndef STRATUM_STRATUM_H
#define STRATUM_STRATUM_H

#include <sys/types.h>
#include <sys/socket.h>
#include <ctime>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <cerrno>
#include <cmath>

#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>

// sudo apt install libmysql++-dev
#include <mysql/mysql.h>
#include <mysql/errmsg.h>

#include <ifaddrs.h>
#include <dirent.h>
#include <iostream>
#include <vector>

#include "json.h"
#include "utils.h"
#include "db.h"


#define STRATUM_RESTART_DELAY      (24*60*60)
#define STRATUM_MAX_JOB_DELAY      (2*60)
#define CURL_RPC_TIMEOUT           30
#define STRATUM_MS                 1000
#define STRATUM_SEC                1000000
#define STRATUM_MAX_ALGOS           32
#define STRATUM_SHARE_PER_SEC      10
#define STRATUM_MIN_DIFF           0x0000000080000000
#define STRATUM_MAX_DIFF           0x4000000000000000
#define STRATUM_SMALL_BUF_SIZE     (32*1024)
#define STRATUM_NONCE_SIZE         4
#define STRATUM_EXTRA_NONCE2_SIZE  4
#define STRATUM_HASH_LEN_STR       65
#define STRATUM_HASH_LEN_BIN       32

typedef void (*STRATUM_HASH_FUNC)(const char*, char*, uint32_t);

extern CommonList g_list_coind;
extern CommonList g_list_client;
extern CommonList g_list_job;
extern CommonList g_list_remote;
extern CommonList g_list_renter;
extern CommonList g_list_share;
extern CommonList g_list_worker;
extern CommonList g_list_block;
extern CommonList g_list_submit;
extern CommonList g_list_source;

extern int g_tcp_port;

extern char g_tcp_server[1024];
extern char g_tcp_password[1024];

extern char g_sql_host[1024];
extern char g_sql_database[1024];
extern char g_sql_username[1024];
extern char g_sql_password[1024];
extern int g_sql_port;

extern char g_stratum_coin_include[256];
extern char g_stratum_coin_exclude[256];

extern char g_stratum_algo[256];
extern double g_stratum_difficulty;
extern double g_stratum_min_diff;
extern double g_stratum_max_diff;

extern int g_stratum_max_cons;
extern int g_stratum_max_ttf;
extern bool g_stratum_reconnect;
extern bool g_stratum_renting;
extern bool g_stratum_segwit;
extern int g_limit_txs_per_block;

extern bool g_handle_haproxy_ips;
extern int g_socket_recv_timeout;

extern bool g_debuglog_client;
extern bool g_debuglog_hash;
extern bool g_debuglog_socket;
extern bool g_debuglog_rpc;
extern bool g_debuglog_list;
extern bool g_debuglog_remote;

extern uint64_t g_max_shares;
extern uint64_t g_shares_counter;

extern bool g_allow_rolltime;
extern time_t g_last_broadcasted;

extern struct ifaddrs *g_ifaddr;

extern pthread_mutex_t g_db_mutex;
extern pthread_mutex_t g_nonce1_mutex;
extern pthread_mutex_t g_job_create_mutex;

extern volatile bool g_exiting;

#endif //STRATUM_STRATUM_H
